package edu.ajou.scw;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Enumeration;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.xslf.usermodel.*;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;

/**
 * Servlet implementation class FileProcessor
 */
@WebServlet("/TeamAction")
public class TeamAction extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public TeamAction() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String id = request.getParameter("id");
		
		String action = request.getParameter("action");
		String member = request.getParameter("member_id");
		
		String json = "";
		
		DatabaseConnector conn = new DatabaseConnector();
		Team t = conn.getTeamById(id);
		
		if (action == null || action.equals("get"))
		{
			if (!id.equals("test"))
			{				
				json = t.getJSONString();
			}
			else
			{
				json = "{ \"members\": [\"t\", \"a\", \"b\"] }";
			}
		}
		
		else if (action.equals("add"))
		{
			JSONParser parser = new JSONParser();
			try {
				JSONObject obj = (JSONObject)parser.parse(member);
				JSONArray arr = (JSONArray)obj.get("members");
				
				String[] memberList = new String[arr.size()];
				
				for (int i=0; i<arr.size(); i++)
				{
					memberList[i] = (String)arr.get(i);
				}
				t.invite(memberList);
			} catch (ParseException e) {
				t.invite(member);
				e.printStackTrace();
			}
			
			json = "{ \"result\": \"ok\" }";
		}
		
		else if (action.equals("reject"))
		{
			t.reject(member);
			
			json = "{ \"result\": \"ok\" }";
		}
		
		PrintWriter writer = response.getWriter();
		writer.write(json);
		writer.flush();
		writer.close();
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		ServletContext context = getServletContext();
		
		long now = Calendar.getInstance().getTimeInMillis();
		
		String team_id = Long.toHexString(now);
		String saveFolder = "/" + team_id;
		
		String savePath = context.getRealPath(saveFolder) + "/";
		
		File f = new File(savePath);
		
		if (!f.exists())
			f.mkdir();

		int sizeLimit = 50 * 1024 * 1024;

		
		MultipartRequest mpr = new MultipartRequest(request, savePath, sizeLimit, "UTF-8", new DefaultFileRenamePolicy());
		
		String leader = mpr.getParameter("leader");
		String members = mpr.getParameter("members");
		String type = mpr.getParameter("type");
		if (type == null)
			type = "presentation";
		
		Enumeration<?> fileNames = mpr.getFileNames(); // file object의 이름 반환
		String fileName = mpr.getFilesystemName(fileNames.nextElement()
				.toString()); // 파일의 이름 얻기

		if (fileName == null) {
			Log.d("File Not Found.");
		} else {
			/*
			String type = fileName.substring(fileName.lastIndexOf("."));

			Log.d("File Type : " + type);
			Log.d("Path : " + savePath);
			Log.d("FileName : " + fileName);

			FileInputStream is = new FileInputStream(savePath + fileName);

			ArrayList<String> files = new ArrayList<String>();

			if (type.equals(".ppt")) {
				SlideShow ppt = new SlideShow(is);
				Dimension pgsize = ppt.getPageSize();
				Slide[] slide = ppt.getSlides();
				
				for (int i = 0; i < slide.length; i++) {
					BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);
					Graphics2D graphics = img.createGraphics();

					// clear the drawing area
					graphics.setPaint(Color.white);
					graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));

					// render
					slide[i].draw(graphics);

					// save the output
					String imgName = "slide-" + (i + 1) + ".png";
					String pageUrl = savePath + imgName;

					files.add(imgName);

					ImageMaker.imageToFile(img, pageUrl);
				}
			} 
	
			else if (type.equals(".pptx")){
				XMLSlideShow pptx = new XMLSlideShow(is);
				XSLFSlide[] slide = pptx.getSlides();
				Dimension pgsize = pptx.getPageSize();
				
				for (int i = 0; i < slide.length; i++) {
					BufferedImage img = new BufferedImage(pgsize.width,
							pgsize.height, BufferedImage.TYPE_INT_RGB);
					Graphics2D graphics = img.createGraphics();

					// clear the drawing area
					graphics.setPaint(Color.white);
					graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width,
							pgsize.height));
					
					// render
					slide[i].draw(graphics);

					// save the output
					String imgName = "slide-" + (i + 1) + ".png";
					String pageUrl = savePath + imgName;

					files.add(imgName);

					ImageMaker.imageToFile(img, pageUrl);
				}
			}
			else if (type.equals(".pdf"))
			{
				RandomAccessFile raf = new RandomAccessFile(savePath + fileName, "r");
				FileChannel channel = raf.getChannel();
				ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());

				PDFFile pdfFile = new PDFFile(buf);
				
				int pageCnt = pdfFile.getNumPages();
				
				for (int i=0; i<pageCnt; i++)
				{
					PDFPage page = pdfFile.getPage(i+1, true);
					Image image = page.getImage((int)page.getBBox().getWidth(), (int)page.getBBox().getHeight(), page.getBBox(), null, true, true);
					int width = image.getWidth(null);
					int height = image.getHeight(null);
					BufferedImage img = new BufferedImage(width,
							height, BufferedImage.TYPE_INT_RGB);
					Graphics2D graphics = img.createGraphics();
					graphics.drawImage(image, 0, 0, null);
					
					String imgName = "slide-" + (i + 1) + ".png";
					String pageUrl = savePath + imgName;
					ImageMaker.imageToFile(img, pageUrl);

					files.add(imgName);
				}
				
				raf.close();
			}
			else
			{
				Log.d("Unknown File Type");
				respOut.println("Unknown File Type");
			}

			is.close();
			*/
			PrintWriter respOut = response.getWriter();
			
			Team team = new Team(team_id, leader, type);
			team.parseMembers(members);
			//team.setSlides(files);
			
			team.putIntoDb();
			
			
			//String json = team.getJSONString();
			
			respOut.println("{ \"status\" : \"ok\" }");
			
			/*
			String cmd = "java -jar /home/ubuntu/PConverter.jar " + team_id + " \"" + savePath + fileName + "\"";
			try {
				Process p = Runtime.getRuntime().exec(cmd);
				InputStream in = p.getInputStream();
				int c;
				while ((c = in.read()) != -1)
				{
					System.out.print(c);
				}
				in.close();
				
				p.waitFor();
				p.destroy();
				Log.d("Command: " + cmd);
			} catch (Exception e)
			{
				Log.d("Error on command: " + cmd);
				e.printStackTrace();
			}*/
			Log.d("Team " + team.getId() + " Created.");
			respOut.flush();
			respOut.close();
			
			PConverter conv = new PConverter();
			conv.convert(team_id, savePath + fileName);

			//invite(team.getMembers(), team);
		}
	}
	
	/*
	public void invite(ArrayList<String> members, Team team)
	{
		String message = team.getJSONString();
		PushSender sender = new PushSender();
		
		for (int i=0; i<members.size(); i++)
		{
			String id = members.get(i);
			if (!id.equals(team.leader))
				sender.sendPush(id, "team_info", message);
		}
	}
	*/
}
